//
//  SNPlayerView.m
//  AVPlayerDemo
//
//  Created by sam on 16/3/24.
//  Copyright © 2016年 yiban. All rights reserved.
//

#import "SNPlayerView.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

@interface SNPlayerView ()

@property (nonatomic, strong) UIActivityIndicatorView *activity;/**活动指示器视图*/

@property (nonatomic, assign)  NSTimeInterval totalTime; //总时长
@property (nonatomic, assign)  NSTimeInterval bufferTime;//缓存的进度
@property (nonatomic, assign)  NSTimeInterval currentTime;//当前的播放时间

@property (nonatomic, strong) AVPlayerLayer *avLayer;//播放器layer
@property (nonatomic, strong) AVPlayerItem *playerItem;
@property (nonatomic, strong) AVPlayer *player;//播放器
@property (nonatomic, strong) UISlider *volumeSlider;
@property (nonatomic, strong) id playbackTimeObserver;

@end

@implementation SNPlayerView
#pragma mark -------系统方法--------
- (instancetype)initWithFrame:(CGRect)frame {
	self = [super initWithFrame:frame];
	if (self) {
		if (![self.layer.sublayers containsObject:self.avLayer]) {
			[self.layer insertSublayer:self.avLayer atIndex:0];
			[self addSubview:self.activity];
			self.backgroundColor = [UIColor grayColor];
		}
	}
	return self;
}

- (void)layoutSubviews {
	[super layoutSubviews];
	NSLog(@"frame is %@", NSStringFromCGRect(self.frame));
	NSLog(@"center is %@", NSStringFromCGPoint(self.center));
	self.avLayer.frame = self.bounds;
	self.activity.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
}

- (void)dealloc {
	[self reset];
}

- (void)play {
	[self.player play];
}

- (void)pause {
	[self.player pause];
}

/**
 *  重置播放器
 */
- (void)reset {
	[self removeObserverAndNotification];
	[self pause];//暂停
	[self.avLayer removeFromSuperlayer];//移除播放器layer
	[self.player replaceCurrentItemWithPlayerItem:nil];//替换播放器playerItem
	[self.player removeTimeObserver:self.playbackTimeObserver];
	self.avLayer = nil;
}

#pragma mark -----私有方法-------
//添加观察者和通知
- (void)addObserverAndNotification {
	// AVPlayer播放完成通知
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
	// 监听播放状态
	[self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
	[self addBufferObserver];
}

//缓存观察者
- (void)addBufferObserver {
	// 监听loadedTimeRanges属性
	[self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
	// 缓存中的监听
	[self.player.currentItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
	// 缓存好之后继续播放
	[self.player.currentItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
}

//移除观察者和通知
- (void)removeObserverAndNotification {
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	[self.player.currentItem removeObserver:self forKeyPath:@"status"];
	[self removeBufferObserver];
}

//移除缓存观察者
- (void)removeBufferObserver {
	[self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
	[self.player.currentItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
	[self.player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
}

/**
 *  播放结束
 */
- (void)moviePlayDidEnd:(NSNotification *)notification {
	[self.player seekToTime:kCMTimeZero completionHandler: ^(BOOL finished) {
	}];
}

/**
 *  计算缓存进度
 */
- (NSTimeInterval)availableDuration {
	NSArray *loadedTimeRanges = [self.player.currentItem loadedTimeRanges];
	CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓存区域
	float startSeconds = CMTimeGetSeconds(timeRange.start);
	float durationSeconds = CMTimeGetSeconds(timeRange.duration);
	return startSeconds + durationSeconds;
}

/**
 *  缓存进行中调用
 */
- (void)buffering {
	if (!self.activity.isAnimating) {
		[self.activity startAnimating];
	}
	__block BOOL isBuffering = NO;
	if (isBuffering) {
		return;
	}
	isBuffering = YES;
	[self pause];
	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
		[self play];
		isBuffering = NO;
		if (!self.playerItem.isPlaybackLikelyToKeepUp) {
		    [self buffering];
		}
	});
}

//获取当前时间
- (void)monitoringPlayback {
	__weak typeof(self) weakSelf = self;

	self.playbackTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock: ^(CMTime time) {
	    weakSelf.currentTime = self.playerItem.currentTime.value / self.playerItem.currentTime.timescale;// 计算当前在第几秒
	}];
}

#pragma mark - kvo
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary <NSString *, id> *)change context:(void *)context {
	if ([keyPath isEqualToString:@"status"]) {
		if (self.player.status == AVPlayerStatusReadyToPlay) {
			self.totalTime = CMTimeGetSeconds(self.playerItem.duration);
			[self monitoringPlayback];
		}
		else {
			NSLog(@"播放错误===>%@", self.player.error);
		}
	}
	else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
		self.bufferTime = [self availableDuration];
	}
	else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
		if (self.playerItem.playbackBufferEmpty) {
			[self buffering];
		}
	}
	else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
		// 当缓存好的时候
		if (self.playerItem.playbackLikelyToKeepUp) {
			[self.activity stopAnimating];
		}
	}
}

#pragma mark -----setter---------
- (void)setPlayUrl:(NSURL *)playUrl {
	_currentTime = 0;
	_totalTime = 0;
	_bufferTime = 0;
	_jumpToTime = 0;

	[self.activity startAnimating];
	_playUrl = playUrl;
	//先移除观察者和通知
	[self reset];
    //初始化playerItem
	self.playerItem = [AVPlayerItem playerItemWithURL:_playUrl];
    //替换player的Item
	[self.player replaceCurrentItemWithPlayerItem:self.playerItem];
    //设置avLayer的player
	self.avLayer.player = self.player;
    //把avlayer加到self.layer上
	[self.layer insertSublayer:self.avLayer atIndex:0];

	[self addObserverAndNotification];

	if ([playUrl.scheme isEqualToString:@"file"]) {
        //这里还需要单独处理  播放本地视频的时候  缓存进度需要处理
	}
	[self play];
}

- (void)setJumpToTime:(NSTimeInterval)jumpToTime {
	_jumpToTime = jumpToTime;
	if (_jumpToTime > _totalTime || _jumpToTime < 0) {
		return;
	}
	self.currentTime = _jumpToTime;
	CMTime changedTime = CMTimeMakeWithSeconds(_jumpToTime, 1);
	__weak typeof(self) weakSelf = self;
    //跳转到指定的播放时间
	[self.player seekToTime:changedTime completionHandler: ^(BOOL finished) {
	    [weakSelf.player play];
	}];
}
/**
 *  音量调节
 */
- (void)setVolume:(CGFloat)volume {
	self.volumeSlider.value = volume;
}
/**
 *  亮度调节
 */
- (void)setBrightness:(CGFloat)brightness {
	[UIScreen mainScreen].brightness = brightness;
}

#pragma mark ------getter--------
- (AVPlayerLayer *)avLayer {
	if (_avLayer == nil) {
		_avLayer = [AVPlayerLayer layer];
	}
	return _avLayer;
}

- (AVPlayer *)player {
	if (_player == nil) {
		_player = [AVPlayer playerWithPlayerItem:self.playerItem];
	}
	return _player;
}

- (UIActivityIndicatorView *)activity {
	if (_activity == nil) {
		_activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
		_activity.hidesWhenStopped = YES;
	}
	return _activity;
}
- (CGFloat)volume {
    return self.volumeSlider.value;
}

- (CGFloat)brightness {
    return [UIScreen mainScreen].brightness;
}

- (UISlider *)volumeSlider {
	if (_volumeSlider == nil) {
		MPVolumeView *volumeView = [[MPVolumeView alloc] init];
		for (UIView *view in[volumeView subviews]) {
			if ([view.class.description isEqualToString:@"MPVolumeSlider"]) {
				_volumeSlider = (UISlider *)view;
				break;
			}
		}
		NSError *setCategoryError = nil;
		[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
	}
	return _volumeSlider;
}

@end
